package stores

import (
	"jvm/instructions/base"
	"jvm/rtda"
	. "jvm/typedef"
)

// 将操作数栈顶弹出的变量放到局部变量表的指定索引处
// 索引由操作码自带或操作数给出。

// *****************************************************************
// istore_x操作通用函数
func istore(frame *rtda.Frame, index U2) {
	localVars := frame.LocalVars()
	stack := frame.OPStack()
	localVars.SetInt(index, stack.PopInt())
}

// *****************************************************************
type ISTORE struct {
	base.U1IndexInst
}

func (selt *ISTORE) Execute(frame *rtda.Frame) {
	istore(frame, U2(selt.Index))
}

// *****************************************************************
type ISTORE_0 struct {
	base.NoOperandsInst
}

func (selt *ISTORE_0) Execute(frame *rtda.Frame) {
	istore(frame, 0)
}

// *****************************************************************
type ISTORE_1 struct {
	base.NoOperandsInst
}

func (selt *ISTORE_1) Execute(frame *rtda.Frame) {
	istore(frame, 1)
}

// *****************************************************************
type ISTORE_2 struct {
	base.NoOperandsInst
}

func (selt *ISTORE_2) Execute(frame *rtda.Frame) {
	istore(frame, 2)
}

// *****************************************************************
type ISTORE_3 struct {
	base.NoOperandsInst
}

func (selt *ISTORE_3) Execute(frame *rtda.Frame) {
	istore(frame, 3)
}

// *****************************************************************
// lstore_x操作通用函数
func lstore(frame *rtda.Frame, index U2) {
	localVars := frame.LocalVars()
	stack := frame.OPStack()
	localVars.SetLong(index, stack.PopLong())
}

// *****************************************************************
type LSTORE struct {
	base.U1IndexInst
}

func (selt *LSTORE) Execute(frame *rtda.Frame) {
	lstore(frame, U2(selt.Index))
}

// *****************************************************************
type LSTORE_0 struct {
	base.NoOperandsInst
}

func (selt *LSTORE_0) Execute(frame *rtda.Frame) {
	lstore(frame, 0)
}

// *****************************************************************
type LSTORE_1 struct {
	base.NoOperandsInst
}

func (selt *LSTORE_1) Execute(frame *rtda.Frame) {
	lstore(frame, 1)
}

// *****************************************************************
type LSTORE_2 struct {
	base.NoOperandsInst
}

func (selt *LSTORE_2) Execute(frame *rtda.Frame) {
	lstore(frame, 2)
}

// *****************************************************************
type LSTORE_3 struct {
	base.NoOperandsInst
}

func (selt *LSTORE_3) Execute(frame *rtda.Frame) {
	lstore(frame, 3)
}

// *****************************************************************
// fstore_x操作通用函数
func fstore(frame *rtda.Frame, index U2) {
	localVars := frame.LocalVars()
	stack := frame.OPStack()
	localVars.SetFloat(index, stack.PopFloat())
}

// *****************************************************************
type FSTORE struct {
	base.U1IndexInst
}

func (self *FSTORE) Execute(frame *rtda.Frame) {
	fstore(frame, U2(self.Index))
}

// *****************************************************************
type FSTORE_0 struct {
	base.NoOperandsInst
}

func (self *FSTORE_0) Execute(frame *rtda.Frame) {
	fstore(frame, 0)
}

// *****************************************************************
type FSTORE_1 struct {
	base.NoOperandsInst
}

func (self *FSTORE_1) Execute(frame *rtda.Frame) {
	fstore(frame, 1)
}

// *****************************************************************
type FSTORE_2 struct {
	base.NoOperandsInst
}

func (self *FSTORE_2) Execute(frame *rtda.Frame) {
	fstore(frame, 2)
}

// *****************************************************************
type FSTORE_3 struct {
	base.NoOperandsInst
}

func (self *FSTORE_3) Execute(frame *rtda.Frame) {
	fstore(frame, 3)
}

// *****************************************************************
// dstore_x操作通用函数
func dstore(frame *rtda.Frame, index U2) {
	localVars := frame.LocalVars()
	stack := frame.OPStack()
	localVars.SetDouble(index, stack.PopDouble())
}

// *****************************************************************
type DSTORE struct {
	base.U1IndexInst
}

func (self *DSTORE) Execute(frame *rtda.Frame) {
	dstore(frame, U2(self.Index))
}

// *****************************************************************
type DSTORE_0 struct {
	base.NoOperandsInst
}

func (self *DSTORE_0) Execute(frame *rtda.Frame) {
	dstore(frame, 0)
}

// *****************************************************************
type DSTORE_1 struct {
	base.NoOperandsInst
}

func (self *DSTORE_1) Execute(frame *rtda.Frame) {
	dstore(frame, 1)
}

// *****************************************************************
type DSTORE_2 struct {
	base.NoOperandsInst
}

func (self *DSTORE_2) Execute(frame *rtda.Frame) {
	dstore(frame, 2)
}

// *****************************************************************
type DSTORE_3 struct {
	base.NoOperandsInst
}

func (self *DSTORE_3) Execute(frame *rtda.Frame) {
	dstore(frame, 3)
}

// *****************************************************************
// astore_x操作通用函数
func astore(frame *rtda.Frame, index U2) {
	localVars := frame.LocalVars()
	stack := frame.OPStack()
	localVars.SetRef(index, stack.PopRef())
}

// *****************************************************************
type ASTORE struct {
	base.U1IndexInst
}

func (self *ASTORE) Execute(frame *rtda.Frame) {
	astore(frame, U2(self.Index))
}

// *****************************************************************
type ASTORE_0 struct {
	base.NoOperandsInst
}

func (self *ASTORE_0) Execute(frame *rtda.Frame) {
	astore(frame, 0)
}

// *****************************************************************
type ASTORE_1 struct {
	base.NoOperandsInst
}

func (self *ASTORE_1) Execute(frame *rtda.Frame) {
	astore(frame, 1)
}

// *****************************************************************
type ASTORE_2 struct {
	base.NoOperandsInst
}

func (self *ASTORE_2) Execute(frame *rtda.Frame) {
	astore(frame, 2)
}

// *****************************************************************
type ASTORE_3 struct {
	base.NoOperandsInst
}

func (self *ASTORE_3) Execute(frame *rtda.Frame) {
	astore(frame, 3)
}
